package com.googlecode.groovy_toy_orm

import com.googlecode.groovy_toy_orm.internal.Util
import groovy.transform.ToString

/**
 * @author: DavydovMD
 * Date: 18.04.13
 * Time: 14:20
 */
@ToString(includeNames = true)
public class Field {
    /**
     * Either String or list
     */
    List from
    String name


    /**
     * closure params: Field f, Map m
     * returns map with only one field name and value
     */

    /*
{Field f, Map map ->
     assert f.from.size()==1
     return map[f.from.last()]
 }
*/
    Closure transform = MapperUtil.transform._default()

    /**
     * closure params: Field f, def value
     * returns map
     *
     */

    /*
    {Field f, def value ->
      (f.from.size() == 1) ? [(f.from.last()): value] as Map : [:]
    }
    */

    Closure<Map> transformBack = MapperUtil.transformBack._default()

    public Field(Map params) {
        params.each() {
            assert ["name", "from", "transform", "transformBack"].contains(it.key), "unknown property $it"
        }


        name = params.name
        from = ((params.from!=null) ? (params.from instanceof List ? params.from : [params.from]) : [params.name])
        if (params.transform) transform = params.transform
        if (params.transformBack) transformBack = params.transformBack

    }

    static boolean isSimpleName(String fieldName) {
        return (!fieldName?.contains("."))
    }


    public static String simplifyName(String name) {
        Util.lastToken(name, ".")
    }

    Field copy() {
        //TODO: Warning: this bounds closure to old field object!!! Find a way to fix it (how?!!!!)
        Field newField = new Field(name: this.name, from: new ArrayList(this.from), transform: this.transform, transformBack: this.transformBack)
        transform.delegate = newField
        newField
    }

    Field copy(String prefix) {
        //TODO: Warning: this bounds closure to old field object!!! Find a way to fix it (how?!!!!)
        Field newField = new Field(name: prefix + this.name, from: new ArrayList(this.from), transform: this.transform, transformBack: this.transformBack)
        transform.delegate = newField
        newField
    }

    String getSimpleName() {
        simplifyName(name)
    }
}